/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.resource.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import jodd.util.ThreadUtil;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.google.gson.Gson;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.api.ResultCode;
import org.springblade.core.tool.utils.Func;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.resource.entity.AttachFile;
import org.springblade.resource.entity.AttachLogs;
import org.springblade.resource.entity.AttachTemplate;
import org.springblade.resource.vo.AttachFileVO;
import org.springblade.resource.service.FileBridgeService;
import org.springblade.resource.service.IAttachFileService;
import org.springblade.resource.service.IAttachLogsService;
import org.springblade.resource.service.IAttachTemplateService;
import org.springblade.resource.service.PutinService;
import org.springblade.resource.service.UserWrapper;
import org.springblade.resource.util.FileUtil;
import org.springblade.core.boot.ctrl.BladeController;

/**
 * 文件表 控制器
 *
 * @author BladeX
 * @since 2021-07-21
 */
@RestController
@AllArgsConstructor
@RequestMapping("/attachfile")
@Slf4j
@Api(value = "文件表", tags = "文件表接口")
public class AttachFileController extends BladeController {

	private final IAttachFileService attachFileService;
	private  final  FileBridgeService  fileBridgeService;
	private final IAttachLogsService attachLogsService;
	private final  UserWrapper  userWrapper;
	
	private final IAttachTemplateService attachTemplateService;

	/**
	 * 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入attachFile")
	public R<AttachFile> detail(AttachFile attachFile) {
		AttachFile detail = attachFileService.getOne(Condition.getQueryWrapper(attachFile));
		userWrapper.entityVO(detail);
		return R.data(detail);
	}

	/**
	 * 分页 文件表
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入attachFile")
	public R<IPage<AttachFile>> list(AttachFile attachFile, Query query) {
		IPage<AttachFile> pages = attachFileService.page(Condition.getPage(query), Condition.getQueryWrapper(attachFile));
		pages.getRecords().forEach(vo ->{
			userWrapper.entityVO(vo);
		});
		return R.data(pages);
	}

	/**
	 * 自定义分页 文件表
	 */
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入attachFile")
	public R<IPage<AttachFileVO>> page(AttachFileVO attachFile, Query query) {
		IPage<AttachFileVO> pages = attachFileService.selectAttachFilePage(Condition.getPage(query), attachFile);
		return R.data(pages);
	}

	/**
	 * 新增 文件表
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入attachFile")
	public R save(@Valid @RequestBody AttachFile attachFile) {
		return R.status(attachFileService.save(attachFile));
	}

	/**
	 * 修改 文件表
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入attachFile")
	public R update(@Valid @RequestBody AttachFile attachFile) {
		return R.status(attachFileService.updateById(attachFile));
	}

	/**
	 * 新增或修改 文件表
	 */
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入attachFile")
	public R submit(@Valid @RequestBody AttachFile attachFile) {
		return R.status(attachFileService.saveOrUpdate(attachFile));
	}

	/**
	 * 新增或修改 文件表
	 */
	@PostMapping("/submitwith")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改 with  file", notes = "传入attachFile,file")
	public R submitwith(@Valid @RequestParam String attach,MultipartFile file) {
		
		AttachFile attachFile = new Gson().fromJson(attach, AttachFile.class);
		Long temid = attachFile.getTemplateId();
		if(temid==null) {
			return R.fail(ResultCode.PARAM_MISS,"templateId");
		}
		AttachTemplate tem = attachTemplateService.getById(temid);
		if(tem == null) {
			return R.fail(ResultCode.NOT_FOUND);
		}
		
		if(file !=null) {
			log.info("file size is {}",file.getSize());
			if(file.getSize()>tem.getLimitSize()*1024) {
				return R.fail(ResultCode.METHOD_NOT_SUPPORTED,"the file is too large!");
			}
			if(FileUtil.isNoRule(file.getOriginalFilename())) {
				return R.fail(ResultCode.METHOD_NOT_SUPPORTED,"the file name is wrong!");
			}
			if(!FileUtil.fileType(file.getOriginalFilename()).equals(tem.getTemType())) {
				return R.fail(ResultCode.METHOD_NOT_SUPPORTED,"the file type is wrong!");
			}
		}
		attachFileService.saveOrUpdate(attachFile);
		
		if(file !=null) {
			String uploadPath = fileBridgeService.filePath(attachFile.getId(),file.getOriginalFilename());
			fileBridgeService.copyLocalToDistributed(FileUtil.MultipartFileToFile(file).getPath(), uploadPath, true, true);
			
			attachFile.setLink(uploadPath);
			attachFile.setOriginalName(file.getOriginalFilename());
			attachFileService.updateById(attachFile);
		}
		
		return R.data(attachFile);
	}
	/**
	 * 删除 文件表
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(attachFileService.deleteLogic(Func.toLongList(ids)));
	}
	 /**
     * 下载文件
     */
    @GetMapping("download")
    public void download(@RequestParam Long id, HttpServletResponse response) {
    	AttachFile  t = attachFileService.getById(id);
    	if(t == null) {
    		return;
    	}
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Expires", "0");
        response.setHeader("charset", "utf-8");
        response.setContentType("application/force-download");
        response.setHeader("Content-Transfer-Encoding", "binary");
        response.setHeader("Content-Disposition", "attachment;filename=\"" + t.getOriginalName() + "\"");
        OutputStream os;
        try {
            os = response.getOutputStream();
            fileBridgeService.download(t.getLink(), os);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    final private PutinService  putinService;
    @PostMapping("/putin")
	@ApiOperationSupport(order = 22)
    public R putin(@Valid @RequestParam Long id) {
    	
    	AttachFile attachFile = attachFileService.getById(id);
    	if(attachFile == null) {
    		return R.fail(ResultCode.NOT_FOUND);
    	}
    	
    	AttachLogs  log =new AttachLogs();
    	log.setFileId(attachFile.getId());
    	log.setLogs("开始入库");
    	log.setRateof(5);
    	log.setName(attachFile.getName()+" 入库");
    	log.setStatus(org.springblade.resource.util.Status.Running.ordinal());
    	attachLogsService.save(log);
    	putinService.doSomething(attachFile, log);
    	return R.data(log);
    }
}
